The structured data types are user-defined and consist of components. Each component of a structured data type has its own data type; components can be any type. To express values of structured objects (arrays, records, and sets), you can use a list of values called constructors. Constructors are valid in the TYPE, CONST, VAR, and executable sections of your program. See the "HP Pascal Language Reference Manual" for examples of valid constructors and examples that show how to assign values to individual components of structured objects.
1 – RECORD
A record is a group of components (called fields) that can be of
various data types. Each record component may contain one or
more data items.
Syntax:
[[PACKED]] RECORD [[field-list]] END
END
If field-list is not specified, an empty record is created. The
following is an example of a record type:
RECORD
Part : INTEGER;
Received : RECORD
Month : ( Jan, Feb, Mar, Apr, May, June,
Jul, Aug, Sep, Oct, Nov, Dec );
Day : 1..31;
Year : INTEGER;
END;
END;
1.1 – Field list
The syntax for a field-list is as follows:
{ {{field-identifier},... : [[attribute-list]] type};...
[[; variant-clause]] [[;]] variant-clause [[;]] }
The 'field-identifier' is the name of a field.
The 'attribute-list' is one or more optional identifiers that
provide additional information about the field.
The 'type' is the type of the corresponding field. A field can
be of any type.
The 'variant-clause' is the variant part of a record. A variant
can contain different types or amounts of data at different
times during program execution. The syntax for a variant clause
is as follows:
CASE { [[tag-identifier : ]] [[attribute-list]]
tag-type-identifier}| discriminant-identifier } OF
{{case-label-list} : (field-list)};...
[[ [[;]] OTHERWISE (field-list)]]
The 'tag-identifier' is the name of the tag field. The tag
field is all of the elements between the reserved words CASE and
OF.
The 'attribute-list' is one or more optional identifiers that
provide additional information about the variant.
The 'tag-type-identifier' is the type identifier for the tag
field.
The 'discriminant-identifier' is the name of the formal
discriminant of a schema type. The value of the corresponding
actual discriminant selects the active variant. Once you select
the variant by discrimination, you cannot change it again.
The 'case-label-list' consists of one or more constant values of
the tag field type either separated by commas. A case constant
is either a single constant value (for example, 1) or a range of
values (for example, 5..10).
The 'field-list' consists of the names, types, and attributes of
one or more fields. At the end of a field list, you can specify
another variant clause. The field-list can be empty.
'OTHERWISE' is equivalent to a case label list that contains tag
values (if any) not previously used in the record. The variant
labeled with OTHERWISE is the current variant when the
tag-identifier has a value that does not occur in any of the
case label lists.
The following is an example of a variant record:
RECORD
Part : 1..9999;
CASE On_Order : Boolean OF
TRUE : ( Order_Quantity : INTEGER;
Price : REAL );
FALSE : ( Rec_Quantity : INTEGER;
Cost : REAL );
END;
In this example, the last two fields in the record vary
depending on whether the part is on order. Records for which
the value of the tag-identifier On_Order is TRUE will contain
information about the current order; those for which it is
FALSE, about the previous shipment.
1.2 – Standard record constructor
Record constructors are lists of values that you can use to
initialize a record.
Syntax:
[[data-type]] [ [[{{component},... : component-value};... ]]
[[{CASE [[tag-identifier :]] tag-value OF
[{{component},... : component-value};... ]
OTHERWISE ZERO [[;]] }]] ]
The 'data_type' specifies the constructor's data type. If you
use the constructor in the executable section or in the CONST
section, a data-type identifier is required. Do not use a type
identifier in initial-state specifiers elsewhere in the
declaration section or in nested constructors.
The 'component' specifies a field in the fixed-part of the
record. Fields in the constructor do not have to appear in the
same order as they do in the type definition. (If you choose,
you can specify fields from the variant-part as long as the
fields do not overlap.)
The 'component-value' specifies a value same data type as the
component. These values are compile-time values; if you use the
constructor in the executable section, you can also use run-time
values.
'CASE' provides a constructor for the variant portion of a
record. If the record contains a variant, its constructor must
be the last component in the constructor list.
The 'tag-identifier' specifies the tag-identifier of the variant
portion of the record. This is only required if the variant
part contained a tag-identifier.
The 'tag-value' determines which component list is applicable
according to the variant portion of the record.
'OTHERWISE ZERO' sets all remaining components to their binary
zero value. If you use OTHERWISE ZERO, it must be the last
component in the constructor.
When you specify constructors for a record that contains nested
records, specify the type of the outermost record, but do not
specify the type of the constructors for any nested records.
The following are examples of record variables and possible
standard record constructors:
Example:
TYPE
Player_Rec = RECORD
Wins : INTEGER;
Losses : INTEGER;
Percentage : REAL;
END;
VAR
Player1 : Player_Rec VALUE [Wins: 18; Losses: 3;
Percentage: 21/18]
This record constructor appears in the variable declaration
section, so the constructor type is optional, and compile-time
values are required.
Example:
TYPE
Player_Rec = RECORD
Wins : INTEGER;
Losses : INTEGER;
Percentage : REAL;
END;
VAR
Player1, Player2 : Player_Rec;
{In the executable section}
Player1 := Player_Rec[Wins:18; Losses: y; Percentage: Y+18/18];
This record constructor appears in the executable section, so
the constructor type is required and run-time expressions are
legal.
1.3 – Nonstandard record constructor
Syntax:
[[data-type]] ([[{component-value},...]]
[[tag-value, {component-value},...]])
The 'data_type' specifies the constructor's data type. If you
use the constructor in the executable section, a data-type
identifier is required. Do not use a type identifier in the VAR
or VALUE sections, or for a nested constructor.
The 'component-value' specifies a compile-time value of the same
data type as the component. The compiler assigns the first
value to the first record component, the second value to the
second component, and so forth.
The 'tag-value' specifies a value for the tag-identifier of a
variant record component. The value that you specify as this
component of the constructor determines the types and positions
of the remaining component values (according to the variant
portion of the type definition).
The following is an example of a record variable and a possible
nonstandard record constructor:
Rec : RECORD
Person : VARYING [30] OF CHAR;
Address : RECORD
Number : INTEGER;
Street : VARYING [30] OF CHAR;
Zip : 0..9999;
END;
Age : 0..150:
END;
('Blaise Pascal', (1623, 'Pensees Street', 91662), 39)
2 – ARRAY
An array is a group of components (called elements) that all
have the same data type and share a common identifier. An
individual element of an array is referred to by an ordinal
index (or subscript) that designates the element's position (or
order) in the array.
Syntax:
[[PACKED]] ARRAY [ {[[attribute-list]] index-type},... ] OF
[[attribute-list]] component-type
The 'attribute-list' is one or more optional identifiers that
provide information about the component type.
The 'index-type' is the type of the index, which can be any
ordinal type or discriminated ordinal schema type.
The 'component-type' is the type of the array components, which
can be any type. The components of an array can be another
array.
Example: ARRAY [0..4] OF INTEGER
An array, whose components are themselves arrays, is called a
multidimensional array. An array can have any number of
dimensions, and each dimension can have a different index type.
Example: ARRAY [0..4, 'A'..'D'] OF INTEGER
This array is declared as two-dimensional. To refer to a
component of this two-dimensional array, specify the variable
name followed by the two bracketed index values. For example
X[0,'A'] or X[0]['A'] specify the component in 'X' at position
'0', 'A'.
2.1 – Standard array constructor
Array constructors are lists of values that you can use to
specify an array value.
Syntax:
[[data-type]] [ [[{{{component | component-subrange}},... :
component-value};... ]] [[OTHERWISE component-value [[;]] ]] ]
The 'data-type' specifies the constructor's data type. If you
use the constructor in the executable section or in the CONST
section, a data-type identifier is required. Do not use a type
identifier in initial-state specifiers elsewhere in the
declaration section or in nested constructors.
The 'component' or a 'component-subrange' specifies an element
number to which the component-value applies. You can specify a
subrange of components. Array elements do not have to be
specified in order. The component must be a compile-time value
or constant.
The 'component-value' specifies the value to be assigned to the
array elements in the component-list; the value must be of the
same data type as the array-component type. This value is a
compile-time value; if you use the constructor in the executable
section, you can also use a run-time value.
'OTHERWISE' specifies a value to be assigned to all array
elements that have not already been assigned values.
When using array constructors, you must initialize all elements
of the array; you cannot partially initialize the array.
When you specify constructors for multidimensional arrays in the
executable section, only specify the type of the outermost
array.
2.1.1 – Examples
The following examples show possible constructors for the array
Numbers:
VAR
Numbers : Count VALUE [1..3,5 : 1; 4,6 : 2; 7..9 : 3; 10 : 6];
{or, in the executable section}
Numbers := Count[1..3,5 : 1; 4,6 : 2; 7..9 : 3; 10 : x+3];
These constructors give the first, second, third, and fifth
component the value 1; the fourth and sixth component the value
2; and the seventh, eighth, and ninth components the value 3.
The first constructor gives the tenth component the value 6; the
second constructor, since it is in the executable section, can
assign the run-time value x+3 to the tenth component.
Numbers := Count[4,6 : 2; 7..9 : 3; 10 : x+3; OTHERWISE 1];
To specify constructor values for all remaining elements, you
can use the OTHERWISE clause.
2.2 – Nonstandard array constructor
Syntax:
[[data-type]] ([[{component-value},...]]
[[REPEAT component-value]])
The 'data-type' specifies the constructor's data type. If you
use the constructor in the executable section, a data-type
identifier is required. Do not use a type identifier in the VAR
or VALUE sections, or for a nested constructor.
The 'component-value' specifies the compile-time value to be
assigned to the corresponding array element. The compiler
assigns the first value to the first element, the second value
to the second element, and so forth. If you want to assign more
than one value to more than one consecutive element, you can use
the following syntax for a component-value:
n OF value
For instance, the following component value assigns the value of
15 to the first three components of an array:
VAR
Array1 : ARRAY [1..4] OF INTEGER;
VALUE
Array1 := ( 3 OF 15, 78 );
You cannot use the OF reserved word in a REPEAT clause.
'REPEAT' specifies a value to be assigned to all array elements
that have not already been assigned values.
The following is an example of an array variable and a possible
array constructor:
Result : ARRAY [1..2, 0..4] OF INTEGER;
((0,1,2,3,4),(5,6,7,8,9))
3 – SET
A set is a collection of data items of the same ordinal type
(called the base type). The SET type definition specifies the
values that can be elements of a variable of that type.
Syntax:
[[PACKED]] SET OF [[attribute-list]] base-type
The 'attribute-list' is one or more optional identifiers that
provide additional information about the base type.
The 'base-type' is the ordinal type identifier or type
definition, or discriminated schema type, from which the set
elements are selected. Note that real numbers cannot be
elements of a set type.
Example: SET OF CHAR
Some possible set constructors for this set type are:
['A, 'E', 'I', 'O', 'U']
['B'..'D', 'F'..'H', 'J'..'N', 'P'..'T', 'V'..'Z']
3.1 – Set constructor
Set constructors are lists of values that you can use to
initialize a set. The syntax for set constructors is as
follows:
[[data-type]] [ [[{component-value},...]] ]
The 'data-type' is the data type of the constructor. This
identifier is optional when used in the CONST and executable
sections; do not use this identifier in the TYPE and VAR
sections or in nested constructors.
The 'component-value' specifies values within the range of the
defined data type. Component values can be subranges (..) to
indicate consecutive values that appear in the set definition.
These values are compile-time values; if you use the constructor
in the executable section, you can also use run-time values.
A set having no elements is called an empty set and is written
as empty brackets ([]).
A possible constructor for a variable of type SET OF 35..115 is
the following:
VAR
Numbers : SET OF 35..115 VALUE [39, 67, 110..115];
{In the executable section, run-time expressions are legal:}
Numbers := [39, 67, x+95, 110..115]
The set constructors contain up to nine values: 39, 67, 95 or
x+95, and integers between 110 and 115, inclusive. If the
expression x+95 evaluates to an integer outside the range
35..115, then VSI Pascal includes no set element for that
expression.
4 – File
A file is a sequence of components of the same type. The number
of components is not fixed, so a file can be any length. The
FILE type definition identifies the component type.
Syntax:
[[PACKED]] FILE OF [[attribute-list]] component-type
The 'attribute-list' is one or more optional identifiers that
provide additional information about the file components.
The 'component-type' is the type of the file components which
can be any ordinal, real, pointer, or structured type, except
for the following:
o A nonstatic type
o A structured type with a nonstatic component
o A file type
o A structured type with a file component
The arithmetic, relational, Boolean, and assignment operators
cannot be used with file variables or structures containing file
components. You cannot form constructors of file types.
Example: FILE OF Boolean
This example shows a file of Boolean values. If a variable,
'TRUTHS', is declared of this type, the file buffer is denoted by
TRUTHS^.
4.1 – Text file
VSI Pascal supplies a predefined file type called TEXT. Files of type TEXT are sequences of characters with special markers (end-of-line and end-of-file) added to the file. Although each character of a TEXT file is one file component, the end-of-line marker allows you to process the file line-by-line (using READLN, WRITELN, or EOLN), if you choose. The predeclared file variables INPUT and OUTPUT are files of type TEXT. They refer to the standard input and output files. The file type FILE OF CHAR differs from TEXT files in that FILE OF CHAR allows a single character to be the unit of transfer between a program and its associated I/O devices and that FILE OF CHAR files do not include special markers. FILE OF CHAR components are always read with the READ procedure, and must be read exclusively into variables of type CHAR, including CHAR components of structured variables. You cannot use the EOLN, READLN, and WRITELN routines on FILE OF CHAR files.
4.2 – External and internal files
VSI Pascal makes distinctions between external and internal files. An internal file has a name in a directory and exists outside the context of a VSI Pascal program. An internal file has no name and is not retained after the program finishes execution. A file declared in the program heading is external by default. A file declared in a nested block is internal by default. To change the default for internal files, call the OPEN procedure or specify a filename on the EXTEND, RESET, or REWRITE procedures. The file is then considered external and is retained with the specified name after the program has finished execution. If you open an internal file with the EXTEND, RESET, or REWRITE procedure, the file remains an internal file.